#!/bin/python
import xml.dom.minidom
import glob
import os.path
import sys
import re

from xml.dom.minidom import Node

# [(Key,Value)] -> Key -> Value
# return '' if key not found
def assocFind( lst, key ):
    for k, t in lst:
        if k == key:
            return t
    return ''

# String -> [(Key, Value)]
def loadXml( filename ):
    doc = xml.dom.minidom.parse(filename)
    elems = doc.getElementsByTagName("dict")[0].childNodes
    keys = list(filter( (lambda n : n.nodeName == "key"), elems ))
    stri = list(filter( (lambda n : n.nodeName == "string"), elems))

    couples = [ ( keys[i].firstChild.nodeValue \
                , stri[i].firstChild.nodeValue) \
                    for i in range( 0, len(keys)) ]
    return couples

# String -> String
def hintEncode( n ):
    try:
        return n.replace( " ", "\\ " )
    except UnicodeEncodeError:
        return ""
    finally:
        return ""

header = """
if exists("b:__{0}__") 
    finish 
endif
let b:__{0}__ = 1 

" containers
let [s:f, s:v] = XPTcontainer() 

" inclusion
XPTinclude 
    \ _common/common

XPTemplateDef
"""

# regexp used to transform the content.
withDefault = re.compile( r"\$\{(\d):([^}]*)\}" )
optional = re.compile( r"\$\{(\d):(\w+)\s*\$\{(\d):([^}]*)\}\s*\}" )
tabStop = re.compile( r"\$(\d)" )
cursor = re.compile( r"\$0" )
wrapped = re.compile( 'TM_SELECTED_TEXT' )
regexped = re.compile( r"\$\{([a-zA-Z_]+|\d)\/([^/]*[^\\])\/([^/]*[^\\])\/([^}]*)}" )

regexFirst = re.compile( r"!;!(.*)\$0(.*)_!_" )
regexpPatch = re.compile( r"!;!(.*)\$(\d)(.*)_!_" )

def regexpFixer( s ):
    s2 = regexFirst.sub( r"!;!\1&\2_!_", s )
    s2, n = regexpPatch.subn(r"!;!\1\\\2\3_!_", s2 )

    while n > 0:
        s2, n = regexpPatch.subn( r"!;!\1\\\2\3_!_", s2 )

    return s2
    
# String -> String
def contentEncode( s ):
    rexed = regexped.sub( r"`\1^!;!'.'),'\2','\3'_!_^", s )
    rexedf = regexpFixer( rexed )
    #rexedf = rexed
    s0 = optional.sub( r'`\2...^\2 \`\3\^\4\^^^', rexedf ).replace( "!;!", "S(R(").replace( "_!_", ")")
    s1 = withDefault.sub( r'`\1^\2^', s0 )
    s2 = cursor.sub( r'`cursor^', s1 )
    s3 = tabStop.sub( r'`\1^', s2)
    s4 = wrapped.sub( 'wrapped', s3 )
    return s4

# (String -> ()) -> String -> ()
def convertSnippet( outf, filename ):
    assoc = loadXml( filename )
    content = contentEncode( assocFind( assoc, "content" ))
    outf( "XPT " + assocFind( assoc, "tabTrigger" ) \
        + " hint=" + hintEncode( assocFind( assoc, "name")) )
    outf( content )
    outf( "..XPT" )
    outf( "" )

# Path -> String
def languageOfPath( p ):
    p2, unused = os.path.split( p )
    u2, pf = os.path.split( p2 )
    return pf.replace( ".tmbundle", "" ) + "_XPT_VIM"


# Parameter : the folder to scan and convert snippets :)
if __name__ == "__main__" :
    print( header.format( languageOfPath( sys.argv[1] ) ) )
    for fname in glob.glob( sys.argv[1] + "/*.tmSnippet" ):
        convertSnippet( print, fname )

#oneDay = [
        #]
#toCheck = \
    #["C:\Users\Vince\AppData\Roaming\e\InstalledBundles\ActionScript 3.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\ActionScript.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Active4D.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Ada.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Almost Plain Text (APT).tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Ant.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Apache.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\AppleScript.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\AutoHotKey.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Bulletin Board.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\C#.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\C++ Qt.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\CMake.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\ColdFusion.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Confluence.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Context Free.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\D.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\DokuWiki.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Doxygen.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Eiffel.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Erlang.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\F-Script.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Flex.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Fortran.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\FXScript.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Gettext.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Google Code.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Greasemonkey.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Gri.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Groovy Grails.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Groovy.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\GTDAlt.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Haskell.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\HTML Revised.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\HTML.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Io.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Java Velocity.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\JavaDoc.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Licenses.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Lilypond.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Logo.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Logtalk.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Lua.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Mail.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Matlab.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Maude.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Maven.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\MIPS.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\MoinMoin.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Movable Type.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Nemerle.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Objective-C.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\OCaml.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\OCaml.tmbundle\Support\OCamlSnippets.txt.gz",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Parrot.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Pascal.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Processing.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Propel.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\R.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Scala.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Scilab.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\SSH-Config.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Standard ML.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\SWeave.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\SWIG.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Tcl.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Twiki.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Txt2tags.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\TYPO3.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Vectorscript.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\Widget Creator.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\XQuery.tmbundle\Snippets",
    #"C:\Users\Vince\AppData\Roaming\e\InstalledBundles\YAML.tmbundle\Snippets",
    #]
